home *** CD-ROM | disk | FTP | other *** search
/ ftp.cs.arizona.edu / ftp.cs.arizona.edu.tar / ftp.cs.arizona.edu / icon / newsgrp / group93c.txt / 000026_icon-group-sender _Thu Jul 22 12:40:36 1993.msg < prev    next >
Internet Message Format  |  1994-02-02  |  4KB

  1. Received: by cheltenham.cs.arizona.edu; Thu, 22 Jul 1993 12:27:11 MST
  2. Message-Id: <9307221702.AA20596@uu3.psi.com>
  3. Date: Thu, 22 Jul 93 12:40:36 EDT
  4. From: Jerry Leichter <leichter@lrw.com>
  5. To: ICON-GROUP@cs.arizona.edu
  6. Subject: RE: More on Icon performance
  7. X-Vms-Mail-To: UUCP%"walter!flaubert!norman@uunet.uu.net"
  8. Status: R
  9. Errors-To: icon-group-errors@cs.arizona.edu
  10.  
  11.     I want to create dags, so that I need to check to see if the node I'm
  12.     about to create already exists.  The best way I know of is to create a
  13.     string that is a function of the node's elements, then look for that
  14.     string in a table.  Does anyone else know a better way?
  15.  
  16.     Here's what I'm doing:
  17.  
  18.       procedure newitem(nt, dotpos, cat)
  19.         static cache
  20.         initial { cache := table() }
  21.         s := nt || " " || image(cat) || " " || dotpos
  22.         /cache[s] := item(nt, dotpos, cat)
  23.         return cache[s]
  24.       end
  25.  
  26.     Can anyone suggest something better?  I'm especially interested in
  27.     something less wasteful of string space.
  28.  
  29. What you are using is an inefficient variation of a classic, efficient tech-
  30. nique used in compilers that goes under the name of value numbering.  It
  31. arises in common subexpression removal.  Suppose you had a tree representing
  32. an expression, and wished to find all common subexpressions within it.  A
  33. common subexpression would be a subtree whose leaves were all leaves of the
  34. original tree.
  35.  
  36. Assign to each node in the tree a value as follows:  If the node is a leaf,
  37. assign it a unique value based on what the leaf contains.  (In the compiler
  38. context, a leaf is either a variable or a constant.  The value represents
  39. the particular value or constant.)  If the node is of the form [v1,...,vn],
  40. where the vi's are the value numbers of then node's n children, assign a
  41. value f(v1,...,vn), which is unique among all the value numbers chosen for
  42. the leaves, and among all values for f with different sets of arguments.
  43. Then two nodes represent common subexpressions if and only if they have the
  44. same value number.
  45.  
  46. What you are doing is using "value numbers" that are not numbers, but strings;
  47. and you are using image() for f(), and at the leaves.  While this works, as
  48. you note it's expensive.  If you use numerical values, it's much easier to
  49. build small data strutures in which you can look things up quickly.  (f() is
  50. almost always computed by (a) looking up [v1,...,vn] in an appropriate table -
  51. usually a hash table, but some kind of trie might make sense; (b) if the node
  52. isn't already in the table, incrementing a counter and assigning its value as
  53. the value number.  Given the nature of the leaves in a compiler, it's usually
  54. easy to come up with simple value numbers for them directly.)
  55.  
  56. You'll need some way to distinguish between leaves, which you could still
  57. look up using image(), and interior nodes; and you'd need some representation
  58. of [v1,...,vn].  It's unclear from your code, but if indeed you are only
  59. concerned with binary nodes, and your data structures aren't too large, then
  60. you might be able to get away with 16-bitf value numbers, and represent
  61. [v1,v2] as 2^16*v1+v2, which can be computed and  looked up in a table very
  62. quickly.  More generally, a list would probably make more sense.
  63.  
  64. If certain nodes in the tree have appropriate mathematical properties, it's
  65. possible to adjust the value numbering algorithm to make use of them.  For
  66. example, if we consider "+" to be commutative, so that "a+b" and "b+a" are
  67. to be considered the same subexpression, then we can choose f() so that
  68. f(+,v1,v2) = f(+,v2,v1).  (Generally you'd do this by exchanging f's second
  69. and third arguments before computing it if, say, the second is larger than
  70. the third.)  Without knowing anything about your application, it's impossible
  71. to say whether this trick might be useful.
  72.                             -- Jerry
  73.